#include "WidgetAnchor.h"
#include "Widgets/Widget.h"

void SWidgetAnchor::Fill(RWidgetPtr InWidget)
{
    HorizontalFill(InWidget);
    VerticalFill(InWidget);
}

void SWidgetAnchor::HorizontalFill(TSharedObjectPtr<RWidget> InWidget)
{
    LeftReference=InWidget;
    RightReference=InWidget;
    LeftOffset=0;
    RightOffset=0;
    HorizontalCenterReference.Reset();  
}

void SWidgetAnchor::VerticalFill(TSharedObjectPtr<RWidget> InWidget)
{
    TopReference=InWidget;
    BottomReference=InWidget;
    TopOffset=0;
    BottomOffset=0;
    VerticalCenterReference.Reset();
}

void SWidgetAnchor::CenterIn(TSharedObjectPtr<RWidget> InWidget)
{
    HorizontalCenterReference=InWidget;
    VerticalCenterReference=InWidget;
    HorizontalCenterOffset=0;
    VerticalCenterOffset=0;
    LeftReference.Reset();
    RightReference.Reset();
    TopReference.Reset();
    BottomReference.Reset();
}

void SWidgetAnchor::Clear()
{
    LeftReference.Reset();
    RightReference.Reset();
    HorizontalCenterReference.Reset();

    TopReference.Reset();
    BottomReference.Reset();
    VerticalCenterReference.Reset();
}

// TTuple<SVec2 ,SVec2 > SWidgetAnchor::AnchorWidget(SVec2 InWidgetPosition,SVec2 InWidgetSize)
// {   
//     TTuple<SVec2 /*Position*/ ,SVec2 /*Size*/> Ret=    WH::MakeTuple(InWidgetPosition,InWidgetSize);
    
//     //calculate Horizontal position and size
//     RWidget* LeftWidget=LeftReference.IsValid()? LeftReference.Get().Get() : nullptr;
//     RWidget* RightWidget=RightReference.IsValid()? RightReference.Get().Get(): nullptr;
//     RWidget* HCenterWidget=HorizontalCenterReference.IsValid()? HorizontalCenterReference.Get().Get(): nullptr;
    

//     //six situation
//     if(LeftWidget)
//     {
//         switch(LeftReferenceEdge)
//         {
//             case EHorizontalWidgetEdge::Left:
//             Ret.First.X=LeftWidget->GetPresentAbsolutePosition().X+ LeftOffset.Get();  
//             break;
//             case EHorizontalWidgetEdge::Right:
//             Ret.First.X=LeftWidget->GetPresentAbsolutePosition().X+LeftWidget->GetPresentSize().X + LeftOffset.Get();  
//             break;           
//             case EHorizontalWidgetEdge::Center:
//             Ret.First.X=LeftWidget->GetPresentAbsolutePosition().X+LeftWidget->GetPresentSize().X/2 + LeftOffset.Get();  
//             break;            
//         }

//         if(HCenterWidget)
//         {
//             float Center;
            
//             switch(HorizontalCenterReferenceEdge)
//             {
//                 case EHorizontalWidgetEdge::Left:
//                 Center=HCenterWidget->GetPresentAbsolutePosition().X + HorizontalCenterOffset.Get();
//                 break;
//                 case EHorizontalWidgetEdge::Right:
//                 Center=HCenterWidget->GetPresentAbsolutePosition().X+ HCenterWidget->GetPresentSize().X + HorizontalCenterOffset.Get(); 
//                 break;           
//                 case EHorizontalWidgetEdge::Center:
//                 Center=HCenterWidget->GetPresentAbsolutePosition().X+ HCenterWidget->GetPresentSize().X/2 + HorizontalCenterOffset.Get();
//                 break;                   
//             }
            
//             Ret.Second.X=  (Center- Ret.First.X) *2;

//         }
//         else if(RightWidget)
//         {
//             float Right;
            
//             switch(RightReferenceEdge)
//             {
//                 case EHorizontalWidgetEdge::Left:
//                 Right=RightWidget->GetPresentAbsolutePosition().X-  RightOffset.Get()  ;
//                 break;
//                 case EHorizontalWidgetEdge::Right:
//                 Right=RightWidget->GetPresentAbsolutePosition().X+ RightWidget->GetPresentSize().X-  RightOffset.Get()  ;
//                 break;           
//                 case EHorizontalWidgetEdge::Center:
//                 Right=RightWidget->GetPresentAbsolutePosition().X+ RightWidget->GetPresentSize().X /2-  RightOffset.Get() ;
//                 break; 
//             };

//             Ret.Second.X=Right-Ret.First.X;

//         }
//         else
//         {
//             //only have left constraint
//         }
//     }
//     else if(RightWidget)
//     {
//         float Right;
        
//         switch(RightReferenceEdge)
//         {
//             case EHorizontalWidgetEdge::Left:
//             Right=RightWidget->GetPresentAbsolutePosition().X-  RightOffset.Get()  ;
//             break;
//             case EHorizontalWidgetEdge::Right:
//             Right=RightWidget->GetPresentAbsolutePosition().X+ RightWidget->GetPresentSize().X-  RightOffset.Get()  ;
//             break;           
//             case EHorizontalWidgetEdge::Center:
//             Right=RightWidget->GetPresentAbsolutePosition().X+ RightWidget->GetPresentSize().X /2-  RightOffset.Get() ;
//             break; 
//         };

//         if(HCenterWidget)
//         {
//             float Center;
            
//             switch(HorizontalCenterReferenceEdge)
//             {
//                 case EHorizontalWidgetEdge::Left:
//                 Center=HCenterWidget->GetPresentAbsolutePosition().X + HorizontalCenterOffset.Get();
//                 break;
//                 case EHorizontalWidgetEdge::Right:
//                 Center=HCenterWidget->GetPresentAbsolutePosition().X+ HCenterWidget->GetPresentSize().X + HorizontalCenterOffset.Get(); 
//                 break;           
//                 case EHorizontalWidgetEdge::Center:
//                 Center=HCenterWidget->GetPresentAbsolutePosition().X+ HCenterWidget->GetPresentSize().X/2 + HorizontalCenterOffset.Get();
//                 break;                   
//             }

//             Ret.Second.X=  (Right-Center) *2;
//             Ret.First.X= Right - Ret.Second.X;
//         }
//         else
//         {
//             // only have right constraint
//             Ret.First.X= Right -  Ret.Second.X;
//         }

//     }
//     else if(HCenterWidget)
//     {
//         // only have center constraint
//         float Center;
            
//         switch(HorizontalCenterReferenceEdge)
//         {
//             case EHorizontalWidgetEdge::Left:
//             Center=HCenterWidget->GetPresentAbsolutePosition().X + HorizontalCenterOffset.Get();
//             break;
//             case EHorizontalWidgetEdge::Right:
//             Center=HCenterWidget->GetPresentAbsolutePosition().X+ HCenterWidget->GetPresentSize().X + HorizontalCenterOffset.Get(); 
//             break;           
//             case EHorizontalWidgetEdge::Center:
//             Center=HCenterWidget->GetPresentAbsolutePosition().X+ HCenterWidget->GetPresentSize().X/2 + HorizontalCenterOffset.Get();
//             break;                   
//         }
//         Ret.First.X=  Center-   Ret.Second.X/2;
//     }

//     //calculate vertical position and size

//     RWidget* TopWidget=TopReference.IsValid()? TopReference.Get().Get(): nullptr;
//     RWidget* BottomWidget=BottomReference.IsValid()? BottomReference.Get().Get(): nullptr;
//     RWidget* VCenterWidget=VerticalCenterReference.IsValid()? VerticalCenterReference.Get().Get(): nullptr;

//     //six situation
//     if(TopWidget)
//     {
//         switch(TopReferenceEdge)
//         {
//             case EVerticalWidgetEdge::Top:
//             Ret.First.Y=TopWidget->GetPresentAbsolutePosition().Y+ TopOffset.Get();  
//             break;
//             case EVerticalWidgetEdge::Bottom:
//             Ret.First.Y=TopWidget->GetPresentAbsolutePosition().Y+TopWidget->GetPresentSize().Y + TopOffset.Get();  
//             break;           
//             case EVerticalWidgetEdge::Center:
//             Ret.First.Y=TopWidget->GetPresentAbsolutePosition().Y+TopWidget->GetPresentSize().Y/2 + TopOffset.Get();  
//             break;            
//         }

//         if(VCenterWidget)
//         {
//             float Center;
            
//             switch(VerticalCenterReferenceEdge)
//             {
//                 case EVerticalWidgetEdge::Top:
//                 Center=VCenterWidget->GetPresentAbsolutePosition().Y + VerticalCenterOffset.Get();
//                 break;
//                 case EVerticalWidgetEdge::Bottom:
//                 Center=VCenterWidget->GetPresentAbsolutePosition().Y+ VCenterWidget->GetPresentSize().Y + VerticalCenterOffset.Get(); 
//                 break;           
//                 case EVerticalWidgetEdge::Center:
//                 Center=VCenterWidget->GetPresentAbsolutePosition().Y+ VCenterWidget->GetPresentSize().Y/2 + VerticalCenterOffset.Get();
//                 break;                   
//             }
//             Ret.Second.Y=  (Center- Ret.First.Y) *2;

//         }
//         else if(BottomWidget)
//         {

//             float Bottom;
            
//             switch(BottomReferenceEdge)
//             {
//                 case EVerticalWidgetEdge::Top:
//                 Bottom=BottomWidget->GetPresentAbsolutePosition().Y-  BottomOffset.Get()  ;
//                 break;
//                 case EVerticalWidgetEdge::Bottom:
//                 Bottom=BottomWidget->GetPresentAbsolutePosition().Y+ BottomWidget->GetPresentSize().Y-  BottomOffset.Get()  ;
//                 break;           
//                 case EVerticalWidgetEdge::Center:
//                 Bottom=BottomWidget->GetPresentAbsolutePosition().Y+ BottomWidget->GetPresentSize().Y /2-  BottomOffset.Get() ;
//                 break; 
//             };

//             Ret.Second.Y=Bottom-Ret.First.Y;

//         }else
//         {
            
//         }
//     }
//     else if(BottomWidget)
//     {
//         float Bottom;
            
//         switch(BottomReferenceEdge)
//         {
//                 case EVerticalWidgetEdge::Top:
//                 Bottom=BottomWidget->GetPresentAbsolutePosition().Y-  BottomOffset.Get()  ;
//                 break;
//                 case EVerticalWidgetEdge::Bottom:
//                 Bottom=BottomWidget->GetPresentAbsolutePosition().Y+ BottomWidget->GetPresentSize().Y-  BottomOffset.Get()  ;
//                 break;           
//                 case EVerticalWidgetEdge::Center:
//                 Bottom=BottomWidget->GetPresentAbsolutePosition().Y+ BottomWidget->GetPresentSize().Y /2-  BottomOffset.Get() ;
//                 break; 
//         };

//         if(VCenterWidget)
//         {
//             float Center;
            
//             switch(VerticalCenterReferenceEdge)
//             {
//                 case EVerticalWidgetEdge::Top:
//                 Center=VCenterWidget->GetPresentAbsolutePosition().Y + VerticalCenterOffset.Get();
//                 break;
//                 case EVerticalWidgetEdge::Bottom:
//                 Center=VCenterWidget->GetPresentAbsolutePosition().Y+ VCenterWidget->GetPresentSize().Y + VerticalCenterOffset.Get(); 
//                 break;           
//                 case EVerticalWidgetEdge::Center:
//                 Center=VCenterWidget->GetPresentAbsolutePosition().Y+ VCenterWidget->GetPresentSize().Y/2 + VerticalCenterOffset.Get();
//                 break;                   
//             }

//             Ret.Second.Y=  (Bottom-Center) *2;

//             Ret.First.Y= Bottom - Ret.Second.Y;
//         }
//         else
//         {
//             // only have bottom constraint
//             Ret.First.Y= Bottom -   Ret.Second.Y;
//         }

//     }
//     else if(VCenterWidget)
//     {
//         // only have center constraint
//         float Center;
            
//         switch(VerticalCenterReferenceEdge)
//         {
//             case EVerticalWidgetEdge::Top:
//             Center=VCenterWidget->GetPresentAbsolutePosition().Y + VerticalCenterOffset.Get();
//             break;
//             case EVerticalWidgetEdge::Bottom:
//             Center=VCenterWidget->GetPresentAbsolutePosition().Y+ VCenterWidget->GetPresentSize().Y + VerticalCenterOffset.Get(); 
//             break;           
//             case EVerticalWidgetEdge::Center:
//             Center=VCenterWidget->GetPresentAbsolutePosition().Y+ VCenterWidget->GetPresentSize().Y/2 + VerticalCenterOffset.Get();
//             break;                   
//         }
//         Ret.First.Y=  Center-   Ret.Second.Y/2;
//     }


//     return Ret;
// }